﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using CommonLib;
using DataLibs;

namespace htmlParser {
    public class htmlParser {

        #region Private Fields
        
        htmlData _data;
        
        List<ParseResult> DataList = new List<ParseResult>();
        string _htmlText;
        string _localDomain;

        const string newLinesPattern = @"\r|\n";
        const string htmlCommentsPattern = @"<!--.*-->";
        const string textSpacePattern = @"\s{2,}|\t+";
        const string htmlAtagPatter = @"<a\s*href\s*=\s*""?(?<url>[^""]+)""?\s*>(?<text>.+?)</a";
        const string htmlAsubtagPatter = @"<a\s*href\s*=\s*""?(?<url>[^""]+)""?\s*>(?<text>.+?)$"; 
        
        #endregion

        public string LocalDomain {
            set {
                _localDomain = value;
            }
        }

        public htmlParser(htmlData data) {
            this._data = data;
            _htmlText = data.HTMLText;
        }

        private void getLocalDomain() {
            Match m = Regex.Match(_localDomain, @"http\:\/\/(?<dom>[\w\.\d\-]+)\/");
            GroupCollection groups = m.Groups;
            _localDomain = groups["dom"].Value.ToString();
        }

        private void preprocessing() {
            _htmlText = Regex.Replace(_htmlText, newLinesPattern, string.Empty, RegexOptions.Compiled);
            _htmlText = Regex.Replace(_htmlText, htmlCommentsPattern, string.Empty, RegexOptions.Compiled);
            _htmlText = Regex.Replace(_htmlText, textSpacePattern, string.Empty, RegexOptions.Compiled);
            getLocalDomain();
        }

        private Zona determineZone(string url) {
            if (Regex.IsMatch(url, @"^h?t?t?p?\:?\/?\/?" + _localDomain) || !Regex.IsMatch(url, @"^http")) {
                return Zona.Local;
            } else {
                return Zona.Remote;
            } 
        }

        private void processingSubLinks (string text, ref string txt) {
            Match m = Regex.Match(text, @"^(?<t>.+?)<a\shref");
            GroupCollection g = m.Groups;
            txt = g["t"].Value.ToString();

            //text;
            MatchCollection MatchesCollection = Regex.Matches(text, htmlAsubtagPatter, RegexOptions.Compiled);
            foreach (Match match in MatchesCollection) {
                GroupCollection groups = match.Groups;
                text = groups["text"].Value.ToString();
                if (Regex.IsMatch(groups["text"].Value.ToString(), @"[^<]*<a href.*")) {
                    processingSubLinks(groups["text"].Value, ref text);
                }
                saveParsedData(groups["url"].Value, text);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void processingTegA() {
            MatchCollection MatchesCollection = Regex.Matches(_htmlText, htmlAtagPatter, RegexOptions.Compiled);

            foreach (Match match in MatchesCollection) {
                GroupCollection groups = match.Groups;

                string txt = groups["text"].Value.ToString();

                if (Regex.IsMatch(groups["text"].Value.ToString(), @"[^<]*<a href.*")) {

                    processingSubLinks(groups["text"].Value.ToString(), ref txt);
                }
                saveParsedData(groups["url"].Value, txt);
            }
        }

        private void saveParsedData(string url, string txt) {
            Zona zona = determineZone(url);

            string Url = url;

            if (zona == Zona.Local) {
                Url = Regex.Replace(Url, @"^http\:\/\/", string.Empty, RegexOptions.Compiled);
                Url = Regex.Replace(Url, @"^" + _localDomain + "/?", string.Empty, RegexOptions.Compiled);
                Url = "/" + Url;
            }

            url = string.Empty;
            for (int i = 0; i < Url.Length; i++) {
                url = url + Char2Hex.Convert(Url[i]);
            }

            txt = Regex.Replace(txt, @"<.*>", string.Empty);
            txt = Regex.Replace(txt, @"\\", @"\\\\");
            txt = Regex.Replace(txt, @"\s", @"\ ");

            DataList.Add(new ParseResult(DataLibs.Type.Page, zona, url, txt));
        }

        public List<ParseResult> parsing() {
            
            preprocessing();

            processingTegA();

            return DataList;

        }

    }
}
